#include "lib/common.h"

#define  MAXLINE     1024


int main(int argc, char **argv) 
{
    if (argc != 2) 
    {
        error(1, 0, "usage: select01 <IPaddress>");
    }
    int socket_fd = tcp_client(argv[1], SERV_PORT);

    char recv_line[MAXLINE], send_line[MAXLINE];
    int n;

    fd_set readmask;
    fd_set allreads;
    // FD_ZERO:用来将这个向量的所有元素都设置成 0
    FD_ZERO(&allreads); //通过 FD_ZERO 初始化了一个描述符集合，这个描述符读集合是空的
    // FD_SET:用来把对应套接字 fd 的元素，a[fd]设置成 1
    FD_SET(0, &allreads); //分别使用 FD_SET 将描述符 0，即标准输入，以及连接套接字描述符 3 设置为待检测
    FD_SET(socket_fd, &allreads);

    // 循环检测，这里我们没有阻塞在 fgets 或 read 调用，而是通过 select 来检测套接字描述字有数据可读，
    // 或者标准输入有数据可读。
    for (;;) 
    {
        readmask = allreads; //每次测试完之后，重新设置待测试的描述符集合
        int rc = select(socket_fd + 1, &readmask, NULL, NULL, NULL); //使用 socket_fd+1 来表示待测试的描述符基数

        if (rc <= 0) 
        {
            error(1, errno, "select failed");
        }

        if (FD_ISSET(socket_fd, &readmask)) //连接描述字准备好可读
        {
            n = read(socket_fd, recv_line, MAXLINE); //使用 read 将套接字数据读出
            if (n < 0) 
            {
                error(1, errno, "read error");
            }
            else if (n == 0) 
            {
                error(1, 0, "server terminated \n");
            }
            recv_line[n] = 0;
            fputs(recv_line, stdout);
            fputs("\n", stdout);
        }

        if (FD_ISSET(STDIN_FILENO, &readmask)) //读入后发送给对端
        {
            if (fgets(send_line, MAXLINE, stdin) != NULL) 
            {
                int i = strlen(send_line);
                if (send_line[i - 1] == '\n') 
                {
                    send_line[i - 1] = 0;
                }

                printf("now sending %s\n", send_line);
                ssize_t rt = write(socket_fd, send_line, strlen(send_line));
                if (rt < 0) 
                {
                    error(1, errno, "write failed ");
                }
                printf("send bytes: %zu \n", rt);
            }
        }
    }
}


